<script setup lang="tsx" name="XtxTabs">
import { useSlots, VNode, provide, toRefs } from "vue";
// 外界传递过来的 modelValue，需要和循环时候的 item.name 进行比较，做高亮的处理
const props = defineProps<{
  modelValue: string;
}>();
const emits = defineEmits<{
  (evName: "update:modelValue", panelName: string): void;
  (evName: "tab-click", { name, index }: { name: string; index: number }): void;
}>();
// 点击触发emit自定义事件
const handleClick = (item: VNode, index: number) => {
  emits("update:modelValue", item.props!.name);
  emits("tab-click", {
    name: item.props!.name,
    index,
  });
};
// 使用toref转换后的属性和原来对象是关联的 修改原来的属性视图会更新
const { modelValue } = toRefs(props);
// provide祖先组件提供数据
provide("activeNameValue", modelValue);

// js中通过useSlots拿到插槽信息
const slots = useSlots();
const Tabs = () => {
  // 正常接收数据
  const arr = slots.default?.()!;
  const panels: VNode[] = [];
  arr.forEach((item) => {
    // 处理基本的写法，直接内部写 XtxTabsPanel
    if ((item.type as any).name === "XtxTabsPanel") {
      // 正常的 XtxTabsPanel 节点
      panels.push(item);
    } else {
      if (Array.isArray(item.children)) {
        item.children.forEach((item) => {
          panels.push(item as VNode);
        });
      }
    }
  });
  // 渲染nav
  const navs = (
    <nav>
      {panels?.map((item: VNode, index: number) => {
        return (
          <a
            href="javascript:;"
            key={index}
            class={{
              active: props.modelValue === item.props?.name,
            }}
            // 如果要传参 onclick={()=> 事件名(参数)} 要用{}包裹
            onClick={() => handleClick(item, index)}
          >
            {item.props?.label}
          </a>
        );
      })}
    </nav>
  );
  return <div class="xtx-tabs">{[navs, panels]}</div>;
};
</script>

<template>
  <Tabs />
</template>

<style lang="less">
.xtx-tabs {
  background: #fff;
  > nav {
    height: 60px;
    line-height: 60px;
    display: flex;
    border-bottom: 1px solid #f5f5f5;
    > a {
      width: 110px;
      border-right: 1px solid #f5f5f5;
      text-align: center;
      font-size: 16px;
      &.active {
        border-top: 2px solid @xtxColor;
        height: 60px;
        background: #fff;
        line-height: 56px;
      }
    }
  }
}
</style>
